home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
mg2a_src.zip
/
EXTEND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-16
|
21KB
|
798 lines
/*
* Extended (M-X) commands, rebinding, and
* startup file processing.
*/
#include "def.h"
#include "kbd.h"
#ifndef NO_MACRO
#include "macro.h"
#endif
#ifdef FKEYS
#include "key.h"
#ifndef NO_STARTUP
#ifndef BINDKEY
#define BINDKEY /* bindkey is used by FKEYS startup code */
#endif
#endif
#endif
extern char *strncpy();
extern int rescan();
/* insert a string, mainly for use from macros (created by selfinsert) */
/*ARGSUSED*/
insert(f, n)
int f, n;
{
register char *cp;
char buf[128];
#ifndef NO_MACRO
register int count;
int c;
if(inmacro) {
while(--n >= 0) {
for(count = 0; count < maclcur->l_used; count++) {
if((((c=maclcur->l_text[count]) == '\n') ? lnewline()
: linsert(1, c)) != TRUE) return FALSE;
}
}
maclcur = maclcur->l_fp;
return TRUE;
}
if(n==1) thisflag |= CFINS; /* CFINS means selfinsert can tack on end */
#endif
if(eread("Insert: ", buf, sizeof(buf), EFNEW) == FALSE) return FALSE;
while(--n >= 0) {
cp = buf;
while(*cp) {
if(((*cp == '\n') ? lnewline() : linsert(1, *cp)) != TRUE)
return FALSE;
cp++;
}
}
return TRUE;
}
/*
* Bind a key to a function. Cases range from the trivial (replacing an
* existing binding) to the extremly complex (creating a new prefix in a
* map_element that already has one, so the map_element must be split,
* but the keymap doesn't have enough room for another map_element, so
* the keymap is reallocated). No attempt is made to reclaim space no
* longer used, if this is a problem flags must be added to indicate
* malloced verses static storage in both keymaps and map_elements.
* Structure assignments would come in real handy, but K&R based compilers
* don't have them. Care is taken so running out of memory will leave
* the keymap in a usable state.
*/
static int remap(curmap, c, funct, pref_map)
register KEYMAP *curmap;/* pointer to the map being changed */
int c; /* character being changed */
PF funct; /* function being changed to */
KEYMAP *pref_map; /* if funct==prefix, map to bind to or NULL for new */
/* extern MAP_ELEMENT *ele; must be set before calling */
{
register int i;
int n1, n2, nold;
KEYMAP *mp;
PF *pfp;
MAP_ELEMENT *mep;
KEYMAP *realocmap();
if(ele >= &curmap->map_element[curmap->map_num] || c < ele->k_base) {
if(ele > &curmap->map_element[0] && (funct!=prefix ||
(ele-1)->k_prefmap==NULL)) {
n1 = c - (ele-1)->k_num;
} else n1 = HUGE;
if(ele < &curmap->map_element[curmap->map_num] && (funct!=prefix ||
ele->k_prefmap==NULL)) {
n2 = ele->k_base - c;
} else n2 = HUGE;
if(n1 <= MAPELEDEF && n1 <= n2) {
ele--;
if((pfp = (PF *)malloc((unsigned)(c - ele->k_base+1)
* sizeof(PF))) == NULL) {
ewprintf("Out of memory");
return FALSE;
}
nold = ele->k_num - ele->k_base + 1;
for(i=0; i < nold; i++)
pfp[i] = ele->k_funcp[i];
while(--n1) pfp[i++] = curmap->map_default;
pfp[i] = funct;
ele->k_num = c;
ele->k_funcp = pfp;
} else if(n2 <= MAPELEDEF) {
if((pfp = (PF *)malloc((unsigned)(ele->k_num - c + 1)
* sizeof(PF))) == NULL) {
ewprintf("Out of memory");
return FALSE;
}
nold = ele->k_num - ele->k_base + 1;
for(i=0; i < nold; i++)
pfp[i+n2] = ele->k_funcp[i];
while(--n2) pfp[n2] = curmap->map_default;
pfp[0] = funct;
ele->k_base = c;
ele->k_funcp = pfp;
} else {
if(curmap->map_num >= curmap->map_max &&
(curmap = realocmap(curmap)) == NULL) return FALSE;
if((pfp = (PF *)malloc(sizeof(PF))) == NULL) {
ewprintf("Out of memory");
return FALSE;
}
pfp[0] = funct;
for(mep = &curmap->map_element[curmap->map_num]; mep > ele; mep--) {
mep->k_base = (mep-1)->k_base;
mep->k_num = (mep-1)->k_num;
mep->k_funcp = (mep-1)->k_funcp;
mep->k_prefmap = (mep-1)->k_prefmap;
}
ele->k_base = c;
ele->k_num = c;
ele->k_funcp = pfp;
ele->k_prefmap = NULL;
curmap->map_num++;
}
if(funct == prefix) {
if(pref_map != NULL) {
ele->k_prefmap = pref_map;
} else {
if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
(MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
ewprintf("Out of memory");
ele->k_funcp[c - ele->k_base] = curmap->map_default;
return FALSE;
}
mp->map_num = 0;
mp->map_max = MAPINIT;
mp->map_default = rescan;
ele->k_prefmap = mp;
}
}
} else {
n1 = c - ele->k_base;
if(ele->k_funcp[n1] == funct && (funct!=prefix || pref_map==NULL ||
pref_map==ele->k_prefmap))
return TRUE; /* no change */
if(funct!=prefix || ele->k_prefmap==NULL) {
if(ele->k_funcp[n1] == prefix)
ele->k_prefmap = (KEYMAP *)NULL;
ele->k_funcp[n1] = funct; /* easy case */
if(funct==prefix) {
if(pref_map!=NULL)
ele->k_prefmap = pref_map;
else {
if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
(MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
ewprintf("Out of memory");
ele->k_funcp[c - ele->k_base] = curmap->map_default;
return FALSE;
}
mp->map_num = 0;
mp->map_max = MAPINIT;
mp->map_default = rescan;
ele->k_prefmap = mp;
}
}
} else {
/* this case is the splits */
/* determine which side of the break c goes on */
/* 0 = after break; 1 = before break */
n2 = 1;
for(i=0; n2 && i < n1; i++)
n2 &= ele->k_funcp[i] != prefix;
if(curmap->map_num >= curmap->map_max &&
(curmap = realocmap(curmap)) == NULL) return FALSE;
if((pfp = (PF *)malloc((unsigned)(ele->k_num - c + !n2)
* sizeof(PF))) == NULL) {
ewprintf("Out of memory");
return FALSE;
}
ele->k_funcp[n1] = prefix;
for(i=n1+n2; i <= ele->k_num - ele->k_base; i++)
pfp[i-n1-n2] = ele->k_funcp[i];
for(mep = &curmap->map_element[curmap->map_num]; mep > ele; mep--) {
mep->k_base = (mep-1)->k_base;
mep->k_num = (mep-1)->k_num;
mep->k_funcp = (mep-1)->k_funcp;
mep->k_prefmap = (mep-1)->k_prefmap;
}
ele->k_num = c - !n2;
(ele+1)->k_base = c + n2;
(ele+1)->k_funcp = pfp;
ele += !n2;
ele->k_prefmap = NULL;
curmap->map_num++;
if(pref_map == NULL) {
if((mp = (KEYMAP *)malloc(sizeof(KEYMAP) +
(MAPINIT-1)*sizeof(MAP_ELEMENT))) == NULL) {
ewprintf("Out of memory");
ele->k_funcp[c - ele->k_base] = curmap->map_default;
return FALSE;
}
mp->map_num = 0;
mp->map_max = MAPINIT;
mp->map_default = rescan;
ele->k_prefmap = mp;
} else ele->k_prefmap = pref_map;
}
}
return TRUE;
}
/* reallocate a keymap, used above */
static KEYMAP *realocmap(curmap)
register KEYMAP *curmap;
{
register KEYMAP *mp;
register int i;
VOID fixmap();
extern int nmaps;
if((mp = (KEYMAP *)malloc((unsigned)(sizeof(KEYMAP)+
(curmap->map_max+(MAPGROW-1))*sizeof(MAP_ELEMENT)))) == NULL) {
ewprintf("Out of memory");
return NULL;
}
mp->map_num = curmap->map_num;
mp->map_max = curmap->map_max + MAPGROW;
mp->map_default = curmap->map_default;
for(i=curmap->map_num; i--; ) {
mp->map_element[i].k_base = curmap->map_element[i].k_base;
mp->map_element[i].k_num = curmap->map_element[i].k_num;
mp->map_element[i].k_funcp = curmap->map_element[i].k_funcp;
mp->map_element[i].k_prefmap = curmap->map_element[i].k_prefmap;
}
for(i=nmaps; i--; ) {
if(map_table[i].p_map == curmap) map_table[i].p_map = mp;
else fixmap(curmap, mp, map_table[i].p_map);
}
ele = &mp->map_element[ele - &curmap->map_element[0]];
return mp;
}
/* fix references to a reallocated keymap (recursive) */
static VOID fixmap(curmap, mp, mt)
register KEYMAP *mt;
register KEYMAP *curmap;
KEYMAP *mp;
{
register int i;
for(i = mt->map_num; i--; ) {
if(mt->map_element[i].k_prefmap != NULL) {
if(mt->map_element[i].k_prefmap == curmap)
mt->map_element[i].k_prefmap = mp;
else fixmap(curmap, mp, mt->map_element[i].k_prefmap);
}
}
}
/*
*